﻿using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

namespace LazyFramework.Game
{
    public class ActorBaseSystem : ComponentSystem
    {
        struct SpawnRandomInSphereInstance
        {
            public int spawnerIndex;
            public Entity sourceEntity;
            public float3 position;
        }

        EntityQuery m_MainGroupEntity;

        protected override void OnCreate()
        {
            m_MainGroupEntity = GetEntityQuery(typeof(ActorBase), typeof(Translation));
        }

        protected override void OnUpdate()
        {
            Debug.Log("OnUpdate +++++++++++++++++++++++++++++++++++++ OnUpdate");
            var uniqueTypes = new List<ActorBase>(10);

            EntityManager.GetAllUniqueSharedComponentData(uniqueTypes);

            int spawnInstanceCount = 0;
            for (int sharedIndex = 0; sharedIndex != uniqueTypes.Count; sharedIndex++)
            {
                var spawner = uniqueTypes[sharedIndex];
                m_MainGroupEntity.SetFilter(spawner);
                var entities = m_MainGroupEntity.ToEntityArray(Allocator.TempJob);
                spawnInstanceCount += entities.Length;
                entities.Dispose();
            }

            if (spawnInstanceCount == 0)
                return;

            var spawnInstances = new NativeArray<SpawnRandomInSphereInstance>(spawnInstanceCount, Allocator.TempJob);
            {
                int spawnIndex = 0;
                for (int sharedIndex = 0; sharedIndex != uniqueTypes.Count; sharedIndex++)
                {
                    var spawner = uniqueTypes[sharedIndex];
                    m_MainGroupEntity.SetFilter(spawner);
                    var entities = m_MainGroupEntity.ToEntityArray(Allocator.TempJob);
                  //  var positions = m_MainGroupEntity.ToComponentDataArray<Translation>(Allocator.TempJob);

                    for (int entityIndex = 0; entityIndex < entities.Length; entityIndex++)
                    {
                        var spawnInstance = new SpawnRandomInSphereInstance();

                        spawnInstance.sourceEntity = entities[entityIndex];
                        spawnInstance.spawnerIndex = sharedIndex;
                     //   spawnInstance.position = positions[entityIndex].Value;

                        spawnInstances[spawnIndex] = spawnInstance;
                        spawnIndex++;
                    }
                    entities.Dispose();
                }
            }

            for (int spawnIndex = 0; spawnIndex < spawnInstances.Length; spawnIndex++)
            {
                int spawnerIndex = spawnInstances[spawnIndex].spawnerIndex;
                var spawner = uniqueTypes[spawnerIndex];
                int count = spawner.count;
                var entities = new NativeArray<Entity>(count, Allocator.TempJob);
                var prefab = spawner.prefab;
                
                var spawnPositions = new NativeArray<float3>(count, Allocator.TempJob);
                var sourceEntity = spawnInstances[spawnIndex].sourceEntity;
                EntityManager.Instantiate(prefab, entities);
                GeneratePoints.RandomPointsInSphere(float3.zero, 1f,  spawnPositions);
                for (int i = 0; i < count; i++)
                {
                    var position = new Translation
                    {
                        Value = new float3(spawnPositions[i].x + 2, spawnPositions[i].y, spawnPositions[i].z)
                    };
                    EntityManager.SetComponentData(entities[i], position);
                }

                EntityManager.RemoveComponent<ActorBase>(sourceEntity);

                spawnPositions.Dispose();
                entities.Dispose();
            }
            spawnInstances.Dispose();
            Debug.Log("OnUpdate --------------------------------- OnUpdate");
        }
    }
}
